home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / BUFFERS.C < prev    next >
C/C++ Source or Header  |  1990-08-01  |  4KB  |  136 lines

  1. /* receive buffer allocation routines */
  2. /* used to provide buffers that can be gotten at interrupt time */
  3.  
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "buffers.h"
  7.  
  8. #if (defined(MSDOS) && !defined(MSC))
  9. # include "alloc.h"
  10. #endif
  11.  
  12. static unsigned max_rxbufs = 0;        /* max number of rx bufs */
  13. static unsigned min_bufsize = MINRXBUFSIZ; /* min size of buffers */
  14. static unsigned max_bufsize = MAXRXBUFSIZ; /* max size of buffers */
  15.  
  16. unsigned cur_rxbufs = 0;        /* number of pre-allocated rx bufs */
  17. struct mbuf *sys_rxbufs = NULLBUF;    /* list of pre-allocated buffers */
  18. struct mbuf *sys_txfree = NULLBUF;    /* list of buffers freed by transmitter */
  19.  
  20. /* "buffers" command sets the number of receive buffers */
  21.  
  22. int
  23. dobuffers (argc,argv)
  24. int argc;
  25. char *argv[];
  26.  
  27. {
  28.     if (argc == 1)
  29.         printf("%u buffers of %u .. %u bytes\n",max_rxbufs,
  30.            min_bufsize,max_bufsize);
  31.     else{
  32.         max_rxbufs = atoi(argv[1]);
  33.         if (argc > 2)
  34.         min_bufsize = atoi(argv[2]);
  35.         if (argc > 3)
  36.         max_bufsize = atoi(argv[3]);
  37.         if (min_bufsize < 2)
  38.         min_bufsize = MINRXBUFSIZ;
  39.         if (max_bufsize < min_bufsize)
  40.         max_bufsize = min_bufsize;
  41.     }
  42.  
  43.     buf_alloc();            /* alloc initial set of buffers */
  44.     return 0;
  45. }
  46.  
  47. /* check if enough buffers are on the receive buffer list
  48.  * if not, allocate them and link to the list
  49.  * also, buffers on the tx "to be freed" list are freed
  50.  * malloc and free are only called with interrupts enabled,
  51.  * because overruns will occur during the free list scan...
  52.  */
  53. void
  54. buf_alloc()
  55. {
  56.     register struct mbuf *bp;
  57.     unsigned bufsize;
  58.     int i_state;
  59. #if (defined(ATARI_ST) && defined(MWC))
  60.     struct memblock {            /* MW C freelist structure */
  61.     long size;
  62.     struct memblock *next;
  63.     };
  64.     extern struct memblock *_a_scanp;    /* current start of scan */
  65.     long blocksize;
  66. #endif
  67. #if (defined(MSDOS) && !defined(MSC))
  68.     extern HEADER PTR allocp;        /* current start of scan */
  69.     unsigned blocksize;
  70. #endif
  71.  
  72.     while (sys_txfree != NULLBUF){    /* buffers to be freed */
  73.     i_state = disable();
  74.     bp = sys_txfree;        /* unlink one buffer */
  75.     sys_txfree = bp->next;
  76.     restore(i_state);
  77.  
  78.     free(bp);            /* free it with ints enabled */
  79.     }
  80.  
  81.     while (cur_rxbufs < max_rxbufs){
  82.     bufsize = max_bufsize;        /* allocate maximum buffer */
  83.  
  84.     /* this piece of code tries to minimize the free list fragmentation
  85.      * by taking a small block from the free list as a receive buffer.
  86.      * any block between MIN and MAX bufsize will be allocated, resulting
  87.      * in many exact fit allocations.
  88.      */
  89.  
  90. #if (defined(ATARI_ST) && defined(MWC))
  91.     if (_a_scanp->size & 1)        /* pointing to a free block? */
  92.     {
  93.         /* when free, check if next also free and join if so */
  94.  
  95.         while ((blocksize = ((struct memblock *) ((char *) _a_scanp + _a_scanp->size - 1))->size) & 1)
  96.         {
  97.         /* join next (free) block with this one */
  98.         _a_scanp->size += blocksize - 1;
  99.         }
  100.  
  101.         /* joined free blocks, now check if within limits */
  102.         /* compute blocksize = sizeof(free block) - sizeof(struct mbuf) */
  103.  
  104.         blocksize = _a_scanp->size - 1 - sizeof(long) - sizeof(struct mbuf);
  105.  
  106.         if (blocksize >= min_bufsize &&    /* big enough? */
  107.         blocksize <= max_bufsize)    /* not too big? */
  108.         {
  109.         bufsize = (int) blocksize;
  110.         }
  111.     }
  112. #endif
  113. #if (defined(MSDOS) && !defined(MSC))
  114.     /* compute blocksize = sizeof(free block) - sizeof(struct mbuf) */
  115.  
  116.     blocksize = allocp->s.size * sizeof(HEADER) - sizeof(HEADER) - sizeof(struct mbuf);
  117.  
  118.     if (blocksize >= min_bufsize &&        /* big enough? */
  119.         blocksize <= max_bufsize)        /* not too big? */
  120.     {
  121.         bufsize = blocksize;
  122.     }
  123. #endif
  124.  
  125.     if ((bp = alloc_mbuf(bufsize)) == NULLBUF)
  126.         break;            /* no space, try again later */
  127.  
  128.     i_state = disable();
  129.     bp->next = sys_rxbufs;        /* link at head of chain */
  130.     sys_rxbufs = bp;
  131.     cur_rxbufs++;
  132.     restore(i_state);
  133.     }
  134. }
  135.  
  136.